package com.zipking.cloud.springbootmybatis.util;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;

/**
 * 提高开发效率，这里设置多线程处理策略
 */
public class SimpleThreadExecuteUtils<T> {

    /**
     * 待执行的数据集合
     */
    private ArrayList<T> list;

    /**
     * 执行任务的线程池
     */
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 当前任务最大并发线程数
     */
    private int loadThread;


    /**
     * 将数据集合交于指定线程处理
     */
    public SimpleThreadExecuteUtils(ArrayList<T> list, ThreadPoolTaskExecutor pool,int loadThread){
        this.list = list;
        this.loadThread = loadThread;
        this.threadPoolTaskExecutor = pool;
    }


    /**
     * 执行任务的方法
     */
    public void Execute(Class Thread){
        //程序计时
        long startTime = System.currentTimeMillis();

        //健壮性判断
        if (null!=list && list.size()>0 && null!=threadPoolTaskExecutor && loadThread>0){
            //计算每组数据量
            int load = list.size()/loadThread;
            System.out.println("数据量："+list.size()+"，每条线程执行的数量"+load);
            CountDownLatch countDownLatch = new CountDownLatch(loadThread);
            try{
                //数据分组，启动线程
                for (int i=0;i<loadThread;i++){
                    //最后一条线程处理所有任务
                    if (i==(loadThread-1)){
                        List<T> ts = list.subList(i * load, list.size());
                        threadPoolTaskExecutor.submit((Callable<? extends Object>) Thread.getConstructor(List.class,String.class,CountDownLatch.class).newInstance(ts,"线程"+i,countDownLatch));
                    }else {
                        List<T> ts = list.subList(i * load, i * load + load);
                        threadPoolTaskExecutor.submit((Callable<? extends Object>) Thread.getConstructor(List.class,String.class,CountDownLatch.class).newInstance(ts,"线程"+i,countDownLatch));
                    }
                }

                //等待所有线程执行完毕
                countDownLatch.await();
            }catch (Exception e){
                e.printStackTrace();
            }

            long endTime = System.currentTimeMillis();
            System.out.println("本次方法耗时："+(endTime-startTime));
        }
    }

}
